package cn.syy.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.syy.constants.GlobalExceptionCode;
import cn.syy.mapper.DriverAuthMaterialMapper;
import cn.syy.pojo.domain.Driver;
import cn.syy.pojo.domain.DriverAuthMaterial;
import cn.syy.pojo.domain.DriverMaterialAuthLog;
import cn.syy.pojo.dto.DriverAuthAuditDto;
import cn.syy.service.IDriverAuthMaterialService;
import cn.syy.service.IDriverMaterialAuthLogService;
import cn.syy.service.IDriverService;
import cn.syy.utils.AssertUtil;
import cn.syy.utils.BitStatesUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;




/**
 * <p>
 * 司机实名资料 服务实现类
 * </p>
 *
 * @author sysyy
 * @since 2024-07-27
 */
@Service
public class DriverAuthMaterialServiceImpl extends ServiceImpl<DriverAuthMaterialMapper, DriverAuthMaterial> implements IDriverAuthMaterialService {

    @Autowired
    private IDriverService driverService;
    @Autowired
    private IDriverMaterialAuthLogService driverMaterialAuthLogService;

    /**
     * 保存真实信息
     * @param driverAuthMaterial
     */
    @Override
    public void saveRealAuth(DriverAuthMaterial driverAuthMaterial) {
        // 1. 参数校验
        // 2. 业务校验
        long id = StpUtil.getLoginIdAsLong(); // 司机的id
        // 校验该司机是否实名认证过，如果是0和1就说明审核中和审核成功
        List<DriverAuthMaterial> list = super.list(new LambdaQueryWrapper<DriverAuthMaterial>()
                .eq(DriverAuthMaterial::getDriverId, id)
                .in(DriverAuthMaterial::getRealAuthStatus, Arrays.asList(0, 1)));
        // 如果实名信息审核中或审核成功就不需要在实名认证了
        //ollUtil.isEmpty(list)：判断是否实名信息审核中或审核成功是否为空，如果为空就是true，不为空就是false
        // false的话就说明不需要实名认证
        AssertUtil.isTrue(CollUtil.isEmpty(list),GlobalExceptionCode.SERVICE_ERROR);
        // 3. 业务实现
        // 修改实名信息的属性并保存到数据库
        driverAuthMaterial.setId(null);
        driverAuthMaterial.setRealAuthStatus(0);
        driverAuthMaterial.setCreateTime(new Date());
        driverAuthMaterial.setDeleted(false);
        driverAuthMaterial.setDriverId(id);
        driverAuthMaterial.setVersion(0);
        super.save(driverAuthMaterial);

        // 判断司机是否存在
        Driver driver = driverService.getById(id);
        AssertUtil.isNotNull(driver, GlobalExceptionCode.SERVICE_ERROR);
        // 司机存在的话，将司机的位状态增加一个实名认证中，并且保存到数据库
        driver.setBitState(BitStatesUtil.addState(driver.getBitState(), BitStatesUtil.OP_REAL_AUTHENTICATING));
        driverService.saveOrUpdate(driver);
    }

    /**
     * 司机实名信息审核
     * @param driverAuthAuditDto
     */
    @Override
    public void realAuthAudit(DriverAuthAuditDto driverAuthAuditDto) {
        // 1.参数校验
        // 2.业务校验
        // 2.1 校验实名信息是否存在
        Long driverAuthAuditDtoId = driverAuthAuditDto.getId();
        DriverAuthMaterial driverAuthMaterial = super.getById(driverAuthAuditDtoId);
        // 实名信息不存在报错
        AssertUtil.isNotNull(driverAuthMaterial,GlobalExceptionCode.NOT_AUTH_MATERIAL_ERROR);
        // 2.2 校验司机审核状态是否成功
        Long driverId = driverAuthMaterial.getDriverId();
        DriverAuthMaterial driverAuthMaterialPass = super.getOne(new LambdaQueryWrapper<DriverAuthMaterial>()
                .eq(DriverAuthMaterial::getDriverId, driverId)
                .eq(DriverAuthMaterial::getRealAuthStatus, 1)); // 审核状态为成功
        // 如果实名认证信息的审核状态为成功的对象的就报错，因为我们需要的是审核状态不为成功的才需要审核
        AssertUtil.isNull(driverAuthMaterialPass,GlobalExceptionCode.AUTH_MATERIAL_ERROR);

        // 3.业务实现
        // 3.1 存储实名信息审核到数据库和修改司机的位状态
        // 将需要用到的抽取出来，并把重复使用的也抽取出来
        Driver driver = driverService.getById(driverId);
        long id = StpUtil.getLoginIdAsLong(); // 审核人的id
        Date date = new Date();
        String remark = driverAuthAuditDto.getRemark();
        Boolean approve = driverAuthAuditDto.getApprove();
        driverAuthMaterial.setAuditRemark(remark);
        driverAuthMaterial.setAuditUserId(id);
        driverAuthMaterial.setUpdateTime(date);
        driverAuthMaterial.setAuditTime(date);
        if(approve){ // 审核通过
            // 设置审核状态为通过
            driverAuthMaterial.setRealAuthStatus(1);
            // 司机的位状态增加一个实名认证成功
            driver.setBitState(BitStatesUtil.addState(driver.getBitState(),BitStatesUtil.OP_REAL_AUTHENTICATIONED));
        }else { // 审核不通过
            // 设置审核状态为不通过
            driverAuthMaterial.setRealAuthStatus(2);
            // 司机的位状态减少一个实名认证中
            driver.setBitState(BitStatesUtil.removeState(driver.getBitState(),BitStatesUtil.OP_REAL_AUTHENTICATING));
        }
        // 将修改后的数据存储到数据库中
        driverService.updateById(driver);
        super.updateById(driverAuthMaterial);
        // 3.2 存储实名信息到审核日志里
        DriverMaterialAuthLog driverMaterialAuthLog = BeanUtil.copyProperties(driverAuthMaterial, DriverMaterialAuthLog.class); // 复制相同的信息
        driverMaterialAuthLog.setId(null); // 因为复制会复制id，但是日志里可能会有多个审核记录，所以审核日志的id设为空
        driverMaterialAuthLog.setCreateTime(date);
        driverMaterialAuthLog.setVersion(0);
        driverMaterialAuthLog.setAuthMaterialId(id);
        driverMaterialAuthLog.setDeleted(false);
        driverMaterialAuthLogService.save(driverMaterialAuthLog);


    }


}
